using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.CodeDom;
using System.Xml.Serialization;
using System.Collections;
using OpenComposite.EII.Repository;

namespace OpenComposite.EII.Designer.Workflow
{
	public partial class FormSelectBusinessRule : Form
	{
		#region Initialization
		public FormSelectBusinessRule(IServiceProvider serviceProvider, Type typeWorkflowClass,
			Repository.Workflow workflow)
		{
			_typeWFClass = typeWorkflowClass;
			_serviceProvider = serviceProvider;
			_workflow = workflow;

			InitializeComponent();

			_brule = null;
			_result = "";
			_listResolve = new List<OpenComposite.EII.Repository.Workflow.RuleParameterResolve>();
		}
		#endregion

		#region Public Members

		#region Properties
		public Repository.RepositoryBusinessRule SelectedBusinessRule
		{
			get { return _brule; }
		}
		public string SelectedResult
		{
			get { return cboResult.SelectedItem == null ? "" : cboResult.SelectedItem.ToString(); }
		}
		public List<OpenComposite.EII.Repository.Workflow.RuleParameterResolve> ParameterResolve
		{
			get { return _listResolve; }//ruleParameterResolveListBindingSource.List as List<OpenComposite.EII.Repository.Workflow.RuleParameterResolve>; }
		}

		#endregion

		#region Methods
		public void Initialize(int bruleId, string result)
		{
			RepositoryService repSvc = (RepositoryService)_serviceProvider.GetService(typeof(RepositoryService));
			if ( repSvc == null )
				throw new NullReferenceException("RepositoryService not available.");

			// set and show business rule
			_brule = repSvc.GetItem(OpenComposite.EII.Repository.ItemType.BRule, bruleId, false) as Repository.RepositoryBusinessRule;
			showBusinessRule();
			// set and show result string
			_result = result;
			showResult();
		}
		public Dictionary<OpenComposite.EII.Repository.Workflow.RuleParameterResolve, CodeExpression>
			GetRuleParameterResolutionExpression()
		{
			Dictionary<OpenComposite.EII.Repository.Workflow.RuleParameterResolve, CodeExpression> dicParams =
				new Dictionary<OpenComposite.EII.Repository.Workflow.RuleParameterResolve, CodeExpression>();

			foreach ( Repository.Workflow.RuleParameterResolve rpr in _listResolve ) {
				dicParams.Add(rpr, null);
			}

			return dicParams;
		}
		public CodeMethodInvokeExpression GetRuleInvokationExpression(List<CodeExpression> parameters)
		{
			CodeMethodInvokeExpression methinvoke = new CodeMethodInvokeExpression(
				new CodeTypeReferenceExpression("OpenComposite.Orchestration.Rules"),
				this.SelectedBusinessRule.Name,
				parameters.ToArray());
			return methinvoke;
		}
		#endregion

		#endregion

		#region Private Members

		#region Variables
		private Repository.RepositoryBusinessRule _brule;
		private string _result;
		private List<OpenComposite.EII.Repository.Workflow.RuleParameterResolve> _listResolve;
		private Repository.Workflow _workflow;

		private Type _typeWFClass;
		private IServiceProvider _serviceProvider;
		#endregion

		#region Methods
		private void showBusinessRule()
		{
			if ( _brule == null ) {
				txtBRuleName.Text = "";
				txtBRuleDesc.Text = "";
				txtBRuleFormula.Text = "";
				cboResult.Items.Clear();
				_listResolve.Clear();
			} else {
				txtBRuleName.Text = _brule.Name;
				txtBRuleDesc.Text = _brule.Description;
				txtBRuleFormula.Text = _brule.RuleCode;
				cboResult.Items.Clear();
				cboResult.Items.AddRange(_brule.Results.Split(';'));
				showResult();
				fillParameterResolve();
			}
		}

		private void fillParameterResolve()
		{
			if ( _listResolve == null ) {
				_listResolve = new List<OpenComposite.EII.Repository.Workflow.RuleParameterResolve>();
			} else {
				_listResolve.Clear();
			}
			//ruleParameterResolveListBindingSource.Clear();
			if ( _workflow != null ) {
				Dictionary<string, string> parameters = _brule.GetParameters();
				foreach ( WorkflowField field in _workflow.Interface.Fields ) {
					foreach ( KeyValuePair<string,string> item in parameters ) {
						if ( field.Name == item.Key && field.DataType == item.Value ) {
						    parameters.Remove(item.Key);
						    break;
						}
					}
				}
				_brule.SetParameters(parameters);
			}
			string[] strsParams = _brule.Parameters.Split(';');
			foreach ( string sParam in strsParams ) {
				if ( string.IsNullOrEmpty(sParam) ) continue;
				string[] p = sParam.Split(':');
				OpenComposite.EII.Repository.Workflow.RuleParameterResolve rpr =
					new OpenComposite.EII.Repository.Workflow.RuleParameterResolve();
				if ( p.Length > 0 )
					rpr.ParameterName = p[0];
				if ( p.Length > 1 )
					rpr.ParameterDataType = p[1];
				//ruleParameterResolveListBindingSource.Add(rpr);
				_listResolve.Add(rpr);
			}
		}
		private void showResult()
		{
			if ( string.IsNullOrEmpty(_result) ) {
				if ( cboResult.Items.Count > 0 )
					cboResult.SelectedIndex = 0;
			} else {
				cboResult.SelectedIndex = cboResult.FindString(_result);
			}
			if ( cboResult.SelectedIndex == -1 && cboResult.Items.Count > 0 ) {
				cboResult.SelectedIndex = 0;
			}
		}
		#endregion

		#region Event Handler

		private void btnSelectBRule_Click(object sender, EventArgs e)
		{
			OpenComposite.EII.Forms.FormSelectRepositoryEx frm = new OpenComposite.EII.Forms.FormSelectRepositoryEx(_serviceProvider);
			frm.ParentItem = _workflow.ProcessPolicy;
			frm.AllowChangeType = false;
			frm.AllowChangeDomain = true;
			frm.AllowCreateNewItem = false;
			frm.AllowedTypes = new OpenComposite.EII.Repository.ItemType[] {
				OpenComposite.EII.Repository.ItemType.BRule, OpenComposite.EII.Repository.ItemType.Route };
			frm.RepositoryID = Global.Status.CurrentRepositoryId;
			frm.DomainID = Global.Status.CurrentDomainId;
			frm.MultiSelect = false;

			if ( frm.ShowDialog() == DialogResult.OK ) {
				_brule = frm.SelectedItem as Repository.RepositoryBusinessRule;
				showBusinessRule();
			}
		}

		private void tsbtnOK_Click(object sender, EventArgs e)
		{
			if ( cboResult.SelectedIndex == -1 ) {
				MessageBox.Show("Please select the business rule result.", this.Text, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
				return;
			}
			this.DialogResult = DialogResult.OK;
			this.Close();
		}

		private void tsbtnCancel_Click(object sender, EventArgs e)
		{
			this._brule = null;
			this.DialogResult = DialogResult.Cancel;
			this.Close();
		}

		//private void dgvParamResolve_CellContentClick(object sender, DataGridViewCellEventArgs e)
		//{
		//}

		//private void dgvParamResolve_CellClick(object sender, DataGridViewCellEventArgs e)
		//{
		//    if ( e.RowIndex >= 0 && e.ColumnIndex == colValueItem.Index ) {
		//        OpenComposite.EII.Repository.Workflow.RuleParameterResolve rpr = dgvParamResolve.Rows[e.RowIndex].DataBoundItem as OpenComposite.EII.Repository.Workflow.RuleParameterResolve;
		//        FormSelectParameterResolve frm = new FormSelectParameterResolve(_typeWFClass);
		//        Rectangle rect = dgvParamResolve.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, true);
		//        frm.Location = dgvParamResolve.PointToScreen(new Point(rect.Left, rect.Bottom));
		//        frm.SelectedPath = rpr.ParameterResolve;
		//        if ( frm.ShowDialog() == DialogResult.OK )
		//            rpr.ParameterResolve = frm.SelectedPath;
		//    }
		//}

		#endregion

		#endregion

	}
	public class RuleParameterResolveList
	{
		public RuleParameterResolveList()
		{
			_listResolve = new List<OpenComposite.EII.Repository.Workflow.RuleParameterResolve>();
		}
		private List<OpenComposite.EII.Repository.Workflow.RuleParameterResolve> _listResolve;
		public List<OpenComposite.EII.Repository.Workflow.RuleParameterResolve> ResolveList
		{
			get { return _listResolve; }
		}
	}
}